/**
 * Created by chencheng on 2017/6/16.
 */
import { isEmpty } from './checkType';

/**
 * 深度合并对象
 * 文档说明: https://github.com/KyleAMathews/deepmerge
 */
import deepmerge from './deepmerge';
export { deepmerge }

/**
 * 深度clone
 */
import deepClone from './deepClone';
export { deepClone }

/**
 * 跳转页面
 * @param url
 * @param timeout
 */
export const redirect = (url: string, timeout: number) => {
  setTimeout(function () {
    location.href = url || location.href;
  }, timeout || 0);
};


/**
 * 时间格式化
 */
export const dateFormat = (timestamp: number | string, fmt = "yyyy-MM-dd hh:mm:ss") => {
  if (!timestamp) return "-";

  if (timestamp.toString().length == 10) {
    timestamp = timestamp as number * 1000
  }
  const date = new Date(parseInt(timestamp.toString()));

  const o = {
    "y+": date.getFullYear(),
    "M+": date.getMonth() + 1,                  //月份
    "d+": date.getDate(),                       //日
    "h+": date.getHours(),                      //小时
    "m+": date.getMinutes(),                    //分
    "s+": date.getSeconds(),                    //秒
    "q+": Math.floor((date.getMonth() + 3) / 3), //季度
    "S+": date.getMilliseconds()                 //毫秒
  };

  for (let k in o) {
    if (new RegExp("(" + k + ")").test(fmt)) {
      if (k == "y+") {
        fmt = fmt.replace(RegExp.$1, ("" + o[k]).substr(4 - RegExp.$1.length));
      }
      else if (k == "S+") {
        var lens = RegExp.$1.length;
        lens = lens == 1 ? 3 : lens;
        fmt = fmt.replace(RegExp.$1, ("00" + o[k]).substr(("" + o[k]).length - 1, lens));
      }
      else {
        // @ts-ignore
        fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
      }
    }
  }

  return fmt;
};

/**
 * 数组去重
 */
export const uniq = <T>(data: T[]): T[] => Array.from(new Set(data));

/**
 * 转换数组为对象
 */
export const convertArrayToObj = <V = any>(data: V[], extractValueName = "value") => {
  const result: { [index: string]: V } = {}
  data.forEach(item => result[item[extractValueName]] = item);
  return result;
}

/**
 * 空数值默认显示
 */
export const defaultTo = <V = any>(data: V, defaultVal: any): V => isEmpty(data) ? defaultVal : data;

/**
 * 获取a数组不同于b数组的元素
 */
export const differenceOfArray = <T = any>(a: T[], b: T[]) => [...a].filter(x => !b.includes(x));

/**
 * 获取a数组的元素在b数组中存在的元素
 */
export const sameOfArray = <T = any>(a: T[], b: T[]) => [...a].filter(x => b.includes(x));

/**
 * 为数组分组
 * @param data
 * @param size
 * [1,2,3,4] => [[1,2], [3,4]]
 */
export const chunk = <T>(data: T[], size: number): T[][] => {
  return data.reduce((chunks, it, i) => {
    // @ts-ignore
    (chunks[i / size | 0] ??= []).push(it);
    return chunks;
  }, []);
}

/**
 * 减速节流函数
 * @param {Function} fn 需要延迟执行的函数
 * @param {Number} time 延迟时间毫秒
 * @param {Object} context
 * @return {wrapperFn}
 *
 * usage:
     const a_fn = (params) => {}
     const render = throttle(a_fn, 16, null);
     render(1);
     render(2); // 将延迟16毫秒执行
 */
export const throttle = (fn: Function, time = 100, context?: any) => {
  let lock: boolean, args: boolean | any[];

  function later() {
    // reset lock and call if queued
    lock = false;
    if (args) {
      wrapperFn.apply(context, args);
      args = false;
    }
  }

  function wrapperFn(...rest: any[]) {
    if (lock) {
      // called too soon, queue to call later
      args = rest;

    } else {
      // lock until later then call
      lock = true;
      fn.apply(context, rest);
      setTimeout(later, time);
    }
  }

  return wrapperFn;
};


/**
 * 防抖函数
 * @param {Function} fn     回调函数
 * @param {Number} delay    延迟时间
 * @param {Object} [context]  回调函数上下文
 * @returns {Function}
 */
export const debounce = (fn: Function, delay = 100, context?: any) => {
  let timeout: any;

  return function (...args: any[]) {

    clearTimeout(timeout);

    context = context || this;
    // let args = arguments

    timeout = setTimeout(function () {

      fn.apply(context, args);

    }, delay)

  };
};

export const isInnerIp = (ip: string) => {
  return /^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$/.test(ip)
}

/**
 * 生成随机字符串
 */
export const randomString = (length: number = 4) => {
  const chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
  let result = '';
  for (let i = length; i > 0; --i) result += chars[Math.floor(Math.random() * chars.length)];
  return result;
};


/**
 * 将Blod转成String
 */
export const blobToString = (blob: Blob, characterSet: string = 'utf-8') => new Promise((resolve, reject) => {
  const reader = new FileReader();
  reader.readAsText(blob, characterSet);
  reader.onload = () => {
    resolve(reader.result);
  };

  reader.onerror = (e) => {
    reject(e);
  };
});



